gskglrenderer: First class support of repeating-linear-gradient
authorFabio Lagalla <lagfabio@amazon.com>
Tue, 26 Jan 2021 11:46:22 +0000 (12:46 +0100)
committerFabio Lagalla <lagfabio@amazon.com>
Wed, 27 Jan 2021 11:44:10 +0000 (12:44 +0100)
gsk/gl/gskglrenderer.c
gsk/gl/gskglrenderops.c
gsk/gl/gskglrenderopsprivate.h
gsk/gl/opbuffer.h
gsk/resources/glsl/linear_gradient.glsl

index 4807dbfba1b0a0cc8f88c3f1538ce76a8c9ab983..026c827ab596c6b9854db6e2f03eaca9bd301a5a 100644 (file)
@@ -1452,6 +1452,7 @@ render_linear_gradient_node (GskGLRenderer   *self,
       ops_set_linear_gradient (builder,
                                n_color_stops,
                                stops,
+                               gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
                                builder->dx + start->x,
                                builder->dy + start->y,
                                builder->dx + end->x,
@@ -3044,6 +3045,7 @@ apply_linear_gradient_op (const Program          *program,
   glUniform4f (program->linear_gradient.points_location,
                op->start_point[0], op->start_point[1],
                op->end_point[0] - op->start_point[0], op->end_point[1] - op->start_point[1]);
+  glUniform1i (program->linear_gradient.repeat_location, op->repeat);
 }
 
 static inline void
@@ -3385,6 +3387,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   /* linear gradient */
   INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, color_stops);
   INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, num_color_stops);
+  INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, repeat);
   INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, points);
 
   /* radial gradient */
@@ -3742,6 +3745,8 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer   *self,
     break;
 
     case GSK_LINEAR_GRADIENT_NODE:
+      /* Intentional fall-through */
+    case GSK_REPEATING_LINEAR_GRADIENT_NODE:
       render_linear_gradient_node (self, node, builder);
     break;
 
@@ -3812,7 +3817,6 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer   *self,
       render_gl_shader_node (self, node, builder);
     break;
 
-    case GSK_REPEATING_LINEAR_GRADIENT_NODE:
     case GSK_REPEATING_RADIAL_GRADIENT_NODE:
     case GSK_CAIRO_NODE:
     default:
index 8bd420e7bd88d44234bc13c4150d47ec919f0e2d..ec14be1e13c79e98c2827b06e43492c7d70deb5a 100644 (file)
@@ -859,6 +859,7 @@ void
 ops_set_linear_gradient (RenderOpBuilder     *self,
                          guint                n_color_stops,
                          const GskColorStop  *color_stops,
+                         bool                 repeat,
                          float                start_x,
                          float                start_y,
                          float                end_x,
@@ -912,6 +913,7 @@ ops_set_linear_gradient (RenderOpBuilder     *self,
               sizeof (GskColorStop) * real_n_color_stops);
     }
 
+  op->repeat = repeat;
   op->start_point[0] = start_x;
   op->start_point[1] = start_y;
   op->end_point[0] = end_x;
index ada8ed43b2f36944a42e663da7e1043e921e61d6..ccc63ab0741fa20e30349c0f0e7be0791c16d61b 100644 (file)
@@ -119,6 +119,7 @@ struct _Program
       int num_color_stops_location;
       int color_stops_location;
       int points_location;
+      int repeat_location;
     } linear_gradient;
     struct {
       int num_color_stops_location;
@@ -315,6 +316,7 @@ void              ops_set_unblurred_outset_shadow   (RenderOpBuilder         *se
 void              ops_set_linear_gradient (RenderOpBuilder     *self,
                                            guint                n_color_stops,
                                            const GskColorStop  *color_stops,
+                                           bool                 repeat,
                                            float                start_x,
                                            float                start_y,
                                            float                end_x,
index db9b5c9425933e5a50c826325955e53608b6d3c4..4241214a374093b7401f4fb0068a6734967b5a8e 100644 (file)
@@ -146,6 +146,7 @@ typedef struct
   IntUniformValue n_color_stops;
   float start_point[2];
   float end_point[2];
+  bool repeat;
 } OpLinearGradient;
 
 typedef struct
index aa90b846e05c3a43be825560fb697e4d0d45da9c..cc90392c0686f378c3e129e515f592a252088148 100644 (file)
@@ -46,6 +46,7 @@ uniform highp int u_num_color_stops; // Why? Because it works like this.
 #endif
 
 uniform float u_color_stops[6 * 5];
+uniform bool u_repeat;
 
 _NOPERSPECTIVE_ _IN_ vec4 info;
 
@@ -65,6 +66,10 @@ vec4 get_color(int index) {
 void main() {
   float offset = dot(info.xy, info.zw);
 
+  if (u_repeat) {
+    offset = fract(offset);
+  }
+
   if (offset < get_offset(0)) {
     gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
     return;